<template>
  <div>
    <el-upload
      class="video-uploader-component"
      :action="uploadAction"
      :headers="uploadHeaders"
      accept=".mp4,.avi,.mov,.flv,.mkv,.webm"
      :show-file-list="false"
      :on-success="handleUploadSuccess"
      :before-upload="beforeVideoUpload"
      :data="uploadData"
    >
      <div v-if="modelValue" class="video-preview" @click.stop="handlePlayVideo">
        <el-icon color="#409EFF" size="24">
          <VideoPlay />
        </el-icon>
        <span class="video-name">{{fileName}}</span>
      </div>
      <div v-else class="video-upload-icon">
        <el-icon color="#8c939d" size="28">
          <Plus />
        </el-icon>
        <span class="upload-text">上传视频</span>
      </div>
    </el-upload>

    <!-- 视频播放对话框 -->
    <el-dialog
      v-model="videoDialogVisible"
      title="视频播放"
      width="70%"
      :close-on-click-modal="false"
    >
      <div class="video-player-container">
        <video
          ref="videoPlayer"
          :src="getVideoUrl(modelValue)"
          controls
          autoplay
          style="width: 100%; height: auto; max-height: 600px;"
        />
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import $cookie from 'vue-cookies'
import { ElMessage } from 'element-plus'
import { VideoPlay } from '@element-plus/icons-vue'
import { computed, ref } from 'vue'

const uploadHeaders = { Authorization: $cookie.get('Authorization') }
const videoDialogVisible = ref(false)
const videoPlayer = ref(null)

const emit = defineEmits(['update:modelValue', 'upload-success'])

const props = defineProps({
  modelValue: {
    default: '',
    type: String
  },
  fileName: {
    default: '',
    type: String
  },
  // 文件关联信息
  fileJoinId: {
    default: null,
    type: [Number, String]
  },
  fileJoinType: {
    default: null,
    type: [Number, String]
  },
  fileJoinFrom: {
    default: null,
    type: String
  },
  fileJoinField: {
    default: null,
    type: String
  },
  // 是否使用关联上传接口
  useAssociation: {
    default: false,
    type: Boolean
  }
})

const uploadAction = computed(() => {
  if (props.useAssociation) {
    // return http.adornUrl('/admin/file/upload/element/with-association')
    return http.adornUrl('/admin/file/upload/file/with-association')
  }
  // return http.adornUrl('/admin/file/upload/element')
  return http.adornUrl('/admin/file/upload/file')
})

const resourcesUrl = import.meta.env.VITE_APP_RESOURCES_URL

const uploadData = computed(() => {
  if (!props.useAssociation) {
    return {}
  }
  return {
    fileJoinId: props.fileJoinId,
    fileJoinType: props.fileJoinType,
    fileJoinFrom: props.fileJoinFrom,
    fileJoinField: props.fileJoinField
  }
})

/**
 * 视频上传成功
 */
const handleUploadSuccess = (_, file) => {
  // 处理响应数据：可能是字符串或对象
  let filePath = file.response
  if (typeof file.response === 'object' && file.response.data) {
    filePath = file.response.data
  }
  emit('update:modelValue', filePath)

  // 获取视频时长
  const videoFile = file.raw
  const video = document.createElement('video')
  video.preload = 'metadata'
  video.onloadedmetadata = () => {
    emit('upload-success', {
      filePath: filePath,
      duration: video.duration
    })
    URL.revokeObjectURL(video.src)
  }
  video.src = URL.createObjectURL(videoFile)
}

/**
 * 限制视频上传大小和格式
 */
const beforeVideoUpload = (file) => {
  const isVideo = file.type === 'video/mp4' ||
                  file.type === 'video/x-msvideo' ||
                  file.type === 'video/quicktime' ||
                  file.type === 'video/x-flv' ||
                  file.type === 'video/x-matroska' ||
                  file.type === 'video/webm'

  if (!isVideo) {
    ElMessage.error('上传视频只能是mp4/avi/mov/flv/mkv/webm 格式!')
    return false
  }

  const isLt500M = file.size / 1024 / 1024 < 500
  if (!isLt500M) {
    ElMessage.error('上传视频大小不能超过 500MB!')
    return false
  }

  return true
}

/**
 * 处理播放视频
 */
const handlePlayVideo = () => {
  if (props.modelValue) {
    videoDialogVisible.value = true
  }
}

/**
 * 获取视频URL
 * 如果modelValue是完整URL则直接返回，否则需要拼接基础URL
 */
const getVideoUrl = (url) => {
  if (!url) return ''

  // 如果是对象，取url属性
  let videoUrl = typeof url === 'object' ? url.url : url

  if (!videoUrl) return ''

  // 如果已经是完整URL（以http开头），直接返回
  if (videoUrl.startsWith('http://') || videoUrl.startsWith('https://')) {
    return videoUrl
  }

  // 否则拼接基础URL
  return resourcesUrl + videoUrl
}
</script>

<style lang="scss" scoped>
.video-uploader-component :deep(.el-upload) {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;

  .video-upload-icon {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;

    .upload-text {
      margin-top: 8px;
      font-size: 12px;
      color: #8c939d;
    }
  }

  .video-preview {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    cursor: pointer;
    transition: all 0.3s ease;

    &:hover {
      transform: scale(1.05);
    }

    .video-name {
      margin-top: 8px;
      font-size: 12px;
      color: #409EFF;
    }
  }
}

.video-uploader-component :deep(.el-upload:hover) {
  border-color: #409EFF;
}

.video-player-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}
</style>

